Skip to main content

Mass balance — legacy RSMS vs new pipeline (investigation)

Legacy and new RSMS use the same engine executables (Neutshell, BLTM, CXPLT). When mass balance totals diverge, treat inputs to those executables as the first place to look, not the binaries.

Hypothesis checklist

  1. NFQ / flow inputs
    Compare neutral-flow files (or SQL vs API NFQ) for the same scenario date, river, and mile.
    Action: Run new RSMS with an NFQ (or flow file) exported from or identical to the legacy run—e.g. pin the spill at river mile 475 and verify downstream steps match before chasing writer or Parquet parsing.

  2. CTL / scenario bag parity
    Confirm DISPERSION, DECAY_COEFFICIENT, SIMULATION_DURATION, SPILL_*, SPILL_RIVER_MILE / tributary miles, GLOBAL_FLOW_MULTIPLIER, dead-zone lines, and timestep / segments / tolerances match line-for-line with legacy for the same scenario row.

  3. Time / timezone
    Spill clock fields in the CTL (SPILL_DAY, SPILL_MONTH, SPILL_YEAR, SPILL_TIME) must match legacy in the scenario’s timezone. A one-hour shift changes NFQ sampling and can change mass routing.

  4. RMI and river mile index
    Same .rmi and RiverMileIndex.csv (or blob equivalents) as legacy for the basin; any difference in reach lengths or junctions changes transport and summed mass splits.

  5. Post-engine processing
    Only after inputs match: compare how new results derive river vs dead-zone vs total mass (mass_balance.json blobs + rsms_results_storage parsing) against legacy SQL reports or screenshots.

Suggested workflow

  1. Archive legacy CTL + NFQ + .in (or exact NFQ source) for a reference scenario.
  2. Run new worker with the same files (or byte-matched NFQ).
  3. If mass balance still differs, diff CTL and NFQ from new vs legacy; then diff CXPLT/BLTM outputs before the results writer.
  • Scenario dispersion is stored as dispersion_factor (API) and written as DISPERSION in the CTL (legacy SimParams.DispersionFactor).
  • Ohio mainstem miles in the UI/geojson use a different convention than the CTL/plume axis; charts and map matching invert with 981.8 − RM for Ohio mainstem display only (see docs/ / ohioRiverMile.js / mainstem_intersection.py).